/******************************************************************************* 
 * Copyright (c) 2008 xored software, Inc.  
 * 
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/epl-v10.html  
 * 
 * Contributors: 
 *     xored software, Inc. - initial API and Implementation (Yuri Strot) 
 *******************************************************************************/
package com.xored.glance.ui.controls.tree;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.TreeItem;

import com.xored.glance.ui.controls.items.ItemProvider;

/**
 * @author Yuri Strot
 * 
 */
public class TreeItemProvider implements ItemProvider {

	private TreeItemProvider() {
	}

	private static TreeItemProvider INSTANCE;

	public static TreeItemProvider getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new TreeItemProvider();
		}
		return INSTANCE;
	}

	public static TreeItem getItem(Item item) {
		return (TreeItem) item;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#getBackground(org.eclipse
	 * .swt.widgets.Item, int)
	 */
	public Color getBackground(Item item, int index) {
		return getItem(item).getBackground(index);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#getColumnCount(org.eclipse
	 * .swt.widgets.Item)
	 */
	public int getColumnCount(Item item) {
		return getItem(item).getParent().getColumnCount();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#getForeground(org.eclipse
	 * .swt.widgets.Item, int)
	 */
	public Color getForeground(Item item, int index) {
		return getItem(item).getForeground(index);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#getText(org.eclipse.swt.
	 * widgets.Item, int)
	 */
	public String getText(Item item, int index) {
		return getItem(item).getText(index);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#getImage(org.eclipse.swt
	 * .widgets.Item, int)
	 */
	public Image getImage(Item item, int index) {
		return getItem(item).getImage(index);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#getImageBounds(org.eclipse
	 * .swt.widgets.Item, int)
	 */
	public Rectangle getImageBounds(Item item, int index) {
		return getItem(item).getImageBounds(index);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#getTextBounds(org.eclipse
	 * .swt.widgets.Item, int)
	 */
	public Rectangle getTextBounds(Item item, int index) {
		return getItem(item).getTextBounds(index);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#getBounds(org.eclipse.swt
	 * .widgets.Item, int)
	 */
	public Rectangle getBounds(Item item, int index) {
		return getItem(item).getBounds(index);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#getFont(org.eclipse.swt.
	 * widgets.Item, int)
	 */
	public Font getFont(Item item, int index) {
		return getItem(item).getFont(index);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.ui.controls.items.ItemProvider#compare(org.eclipse.swt
	 * .widgets.Item, org.eclipse.swt.widgets.Item)
	 */
	public int compare(Item item1, Item item2) {
		TreeItem[] parents1 = getParents(item1);
		TreeItem[] parents2 = getParents(item2);
		for (int i = 0; i < parents1.length && i < parents2.length; i++) {
			int diff = compareAtLevel(parents1[i], parents2[i]);
			if (diff != 0)
				return diff;
		}
		return parents1.length - parents2.length;
	}

	private int compareAtLevel(TreeItem item1, TreeItem item2) {
		if (item1.equals(item2))
			return 0;
		TreeItem parent = item1.getParentItem();
		TreeItem[] items = parent == null ? item1.getParent().getItems()
				: parent.getItems();
		for (TreeItem item : items) {
			if (item1.equals(item))
				return -1;
			if (item2.equals(item))
				return 1;
		}
		return 0;
	}

	private TreeItem[] getParents(Item item) {
		List<TreeItem> parents = new ArrayList<TreeItem>(10);
		TreeItem cItem = (TreeItem) item;
		while (cItem != null) {
			parents.add(0, cItem);
			cItem = cItem.getParentItem();
		}
		return parents.toArray(new TreeItem[parents.size()]);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#showItem(org.eclipse.swt
	 * .widgets.Item)
	 */
	public void show(Item item) {
		TreeItem tItem = getItem(item);
		tItem.getParent().showItem(tItem);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.internal.items.ItemProvider#select(org.eclipse.swt.widgets
	 * .Item)
	 */
	public void select(Item item) {
		TreeItem tItem = getItem(item);
		tItem.getParent().setSelection(tItem);
	}

}
